#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QtGui>
#include <QGraphicsScene>
#include <QInputDialog>
#include "../newcode/api.h"
#include "encodedialog.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui->graphicsView->scene();
    delete ui;
}

void MainWindow::on_actionOpen_activated()
{
    QString fileName = QFileDialog::getOpenFileName(this,
        "Open Image", ".", "Image Files (*.png *.jpg *.bmp)");  
    if (fileName != NULL && fileName != "") {
        delete ui->graphicsView->scene();
        QGraphicsScene *scene = new  QGraphicsScene(ui->graphicsView);
        image = QImage(fileName);
        scene->addPixmap(QPixmap::fromImage(image));
        ui->graphicsView->setScene(scene);
        ui->statusBar->showMessage("Image Path: " + fileName, 10000);
    }
}

void MainWindow::on_actionAbout_activated()
{
    QMessageBox::about(this, "About Frontend",
                       "Diploma project of Ihar Tumashyk.\n"\
                       "(c) 2012, BSU");
}

unsigned char** MainWindow::getGrey2D(const QImage& image)
{
    unsigned char** data = new unsigned char*[image.height()];
    for (int i = 0; i < image.height(); i++)
    {
        data[i] = new unsigned char[image.width()];
    }
    for (int y = 0; y < image.height(); y++)
    {
        for(int x = 0; x < image.width(); x++)
        {
            data[y][x] = qGray(image.pixel(x, y));
        }
    }
    return data;
}

void MainWindow::drawResult(unsigned char** result, int size)
{
    int delta = 4;
    int field = delta * 3;
    delete ui->graphicsView->scene();
    QGraphicsScene *scene = new  QGraphicsScene(ui->graphicsView);

    int backSize = size * delta + 2 * field - 1;
    QRectF backRect(0, 0, backSize - 1,  backSize - 1);

    scene->addRect(backRect, QPen(QColor(255, 255, 255)),
        QBrush(QColor(255, 255, 255)));
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            if (result[i][j] != 255) {
                int x = i * delta + field;
                int y = j * delta + field;
                QRectF rect(x, y, delta - 1, delta - 1);
                QColor color(result[i][j], result[i][j], result[i][j]);
                scene->addRect(rect, QPen(color), QBrush(color));
            }
        }
    }
    for(int i = 0; i < size; i++) {
        free(result[i]);
    }
    free(result);
    ui->graphicsView->setScene(scene);
}

void MainWindow::on_actionSave_activated()
{
    createImageFromScene();

    QString fileName = QFileDialog::getSaveFileName(this, "Save code",
        "", "PNG Images (*.png)");
    if (fileName != NULL && fileName != "")
    {
        if (!fileName.endsWith(".png", Qt::CaseInsensitive))
        {
            fileName.append(".png");
        }
        image.save(fileName, "PNG", 0);
        ui->statusBar->showMessage("Saved to " + fileName, 10000);
    }

}

void MainWindow::createImageFromScene()
{
    if (ui->graphicsView->scene())
    {
        QRectF sceneRect = ui->graphicsView->scene()->sceneRect();
        QImage image(sceneRect.width(), sceneRect.height(),
            QImage::Format_RGB888);
        QPainter painter(&image);
        ui->graphicsView->scene()->render(&painter);
        this->image = image;
    }
}

void MainWindow::on_actionAboutQT_activated()
{
    QMessageBox::aboutQt(this);
}

void MainWindow::on_actionDecodeAsGreyscaleCode_activated()
{
    createImageFromScene();
    unsigned char** data = getGrey2D(image);
    NC_Error error;
    NC_DecodeResult* result = nc_decode(data, image.width(),
        image.height(), &error);
    if (error.code == ERROR_NO_ERRORS)
    {
        if (result->text != NULL)
        {
            QString message = QString::fromUtf8(result->text);
            QMessageBox::information(this, "Decode result", message);
        }
        else
        {
            QMessageBox::information(this, "Decode result", "<binary data>");
        }
        nc_release_result(result);
    }
    else
    {
        QMessageBox::critical(this, "Error during decode", error.what);
    }
    for (int i = 0; i < image.height(); i++)
    {
        delete[] data[i];
    }
    delete[] data;
}

void MainWindow::on_actionEncodeAsGreyscaleCode_activated()
{
    QString text;
    NC_Mode mode;
    EncodeDialog dialog (&text, &mode, this);
    if (dialog.exec() == QDialog::Accepted)
    {
        int size;
        NC_Error error;
        unsigned char** result = nc_encode(text.toUtf8().data(),mode,
            &size, &error);
        if (error.code == 0)
        {
            drawResult(result, size);
        }
        else
        {
            QMessageBox::critical(this, "Error during encoding", error.what);
        }
    }
}
